#pragma once
#include <list>
#include "vector.h"
#include "plane.h"
#include "boundingsphere.h"
#include "boundingbox.h"

/**
 * Klasa wielokata 3D
 *
 * @author Krzysztof Klein
 * @version 0.1
 */
class Polygon
{

	/**
	 * Lista wierzcholkow
	 */
	std::list<Vector> vertices;

	/**
	 * Plaszczyzna wielokata
	 */
	Plane plane;

	/**
	 * Sfera otaczajaca
	 */
	BoundingSphere boundingSphere;

	/**
	 * Prostopadloscian otaczajacy
	 */
	BoundingBox boundingBox;

public:

	/**
	 * Konstruktor domyslny
	 */
	Polygon() { }


	/**
	 * Lista wierzcholkow
	 *
	 * @return Lista wierzcholkow
	 */
	std::list<Vector>& getVertices() { return vertices; }

	/**
	 * Lista wierzcholkow
	 *
	 * @return Lista wierzcholkow
	 */
	const std::list<Vector>& getVertices() const { return vertices; }


	/**
	 * Plaszczyzna wielokata
	 *
	 * @return Plaszczyzna wielokata
	 */
	Plane& getPlane() { return plane; }

	/**
	 * Plaszczyzna wielokata
	 *
	 * @return Plaszczyzna wielokata
	 */
	const Plane& getPlane() const { return plane; }

	/**
	 * Sfera otaczajaca
	 *
	 * @return Sfera otaczajaca
	 */
	BoundingSphere& getBoundingSphere() { return boundingSphere; }

	/**
	 * Sfera otaczajaca
	 *
	 * @return Sfera otaczajaca
	 */
	const BoundingSphere& getBoundingSphere() const { return boundingSphere; }

	/**
	 * Prostopadloscian otaczajacy
	 *
	 * @return Prostopadloscian otaczajacy
	 */
	BoundingBox& getBoundingBox() { return boundingBox; }

	/**
	 * Prostopadloscian otaczajacy
	 *
	 * @return Prostopadloscian otaczajacy
	 */
	const BoundingBox& getBoundingBox() const { return boundingBox; }


	/**
	 * Oblicza plaszczyzne wielokata
	 */
	void recalculatePlane()
	{
		std::list<Vector>::const_iterator it;
		Vector v[3];
		int i;
		if(vertices.size() < 3)
			return;
		for(i = 0, it = vertices.begin();
				i < 3; i++, it++)
			v[i] = *it;
		plane = Plane(v[0], v[1], v[2]);
	}


	/**
	 * Oblicza sfere otaczajaca
	 */
	void recalculateBoundingSphere()
	{
		boundingSphere = BoundingSphere(vertices);
	}


	/**
	 * Oblicza prostopadloscian otaczajacy
	 */
	void recalculateBoundingBox()
	{
		boundingBox = BoundingBox(vertices);
	}

};
